package com.pateo.bjev.contacts.service;

import android.content.Context;
import android.os.RemoteException;
import com.pateo.bjev.contacts.BtData;
import com.pateo.bjev.contacts.IBtStateListener;
import com.pateo.bjev.contacts.IPbapStateListener;
import com.pateo.bjev.contacts.utils.Log;
import com.pateo.bluetooth.logic.bean.ContactData;
import com.pateo.bluetooth.logic.bean.ContactLog;
import com.pateo.bluetooth.logic.bean.ContactMatchInfo;
import com.pateo.bluetooth.logic.contact.callback.BTEventListener;
import com.pateo.bluetooth.logic.contact.callback.PBAPEventListener;
import com.pateo.bluetooth.logic.contact.manager.ContactsManager;
import com.pateo.bluetooth.logic.util.Constants;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by pateo on 17-5-9.
 */

public class ContactsHandler {

    private ContactsManager manager;

    private int pbapState;

    private List<IBtStateListener> btStateListeners = new LinkedList<>();
    private List<IPbapStateListener> pbapStateListeners = new LinkedList<>();

    protected List<ContactData> contacts = new LinkedList<>();
    protected List<ContactLog> contactLogs = new LinkedList<>();

    public ContactsHandler(Context context){
        manager = ContactsManager.getInstance(context.getApplicationContext());
        manager.registerBTEvent(btEventListener);
        manager.registerPBAPEvent(pbapEventListener);

        pbapState = BtData.PBAP_STATE_NONE;
    }

    protected void unRegisterEvent(){
        if(manager!=null){
            manager.unRegisterBTEvent(btEventListener);
            manager.unRegisterPBAPEvent(pbapEventListener);
        }
    }

    protected void registBtStateListener(IBtStateListener listener){
        if(!btStateListeners.contains(listener)){
            btStateListeners.add(listener);
        }
    }

    protected void unregistBtStateListener(IBtStateListener listener){
        if(btStateListeners.contains(listener)){
            btStateListeners.remove(listener);
        }
    }

    protected void registPbapStateListener(IPbapStateListener listener){
        if(!pbapStateListeners.contains(listener)){
            pbapStateListeners.add(listener);
        }
    }

    protected void unregistPbapStateListener(IPbapStateListener listener){
        if(pbapStateListeners.contains(listener)){
            pbapStateListeners.remove(listener);
        }
    }

    private void notifyBtConnectStateChange(boolean connected){
        for(IBtStateListener listener : btStateListeners){
            if(listener!=null){
                try{
                    if(connected){
                        listener.connected();
                    }else{
                        listener.disconnected();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyContactsSyncStart(){
        for(IPbapStateListener listener:pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onContactsSyncStart();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyCallLogSyncStart(){
        for(IPbapStateListener listener : pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onCalllogSyncStart();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyContactsSyncEnd(List<ContactData> list){
        for(IPbapStateListener listener : pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onContactsSyncEnd(list);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyContactsChanged(List<ContactData> list){
        for(IPbapStateListener listener : pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onContactUpdated(list);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyCallLogSyncEnd(List<ContactLog> list){
        for(IPbapStateListener listener : pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onCalllogSyncEnd(list);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void notifyCallLogChanged(List<ContactLog> list){
        for(IPbapStateListener listener : pbapStateListeners){
            if(listener!=null){
                try {
                    listener.onCallLogUpdated(list);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    protected int getState(){
        if(manager!=null){
            return manager.isBluetoothConnect()?BtData.BT_STATE_CONNECTED:BtData.BT_STATE_DISCONNECTED;
        }
        return BtData.BT_STATE_DISCONNECTED;
    }

    protected int getPbapState(){
        return pbapState;
    }

    private BTEventListener btEventListener = new BTEventListener() {
        @Override
        public void onHfpStateChange(int i) {
            Log.i(ContactsHandler.class,"onHfpStateChange i="+i);
        }

        @Override
        public void onBTStateChange(int i) {
            Log.i(ContactsHandler.class,"onBTStateChange i="+i);
        }

        @Override
        public void onBTConnectionStateChanged(int i) {
            Log.i(ContactsHandler.class,"onBTConnectionStateChanged i="+i);
            boolean connected = false;
            if(i==16){
                connected = true;
            }else if(i == 19){
                connected = false;
            }
            notifyBtConnectStateChange(connected);
        }
    };

    private PBAPEventListener pbapEventListener = new PBAPEventListener() {
        @Override
        public void onHfpStateChange(int i) {
            Log.i(ContactsHandler.class,"onHfpStateChange i="+i);
        }

        @Override
        public void onCallLogItemCountUpdated(int i, int i1) {
            Log.i(ContactsHandler.class,"onCallLogItemCountUpdated i="+i+",i1="+i1);
        }

        @Override
        public void onContactItemCountUpdated(int i, int i1) {
            Log.i(ContactsHandler.class,"onContactItemCountUpdated i="+i+",i1="+i1);
        }

        @Override
        public void onSyncContactStateChanged(int i) {
            Log.i(ContactsHandler.class,"onSyncContactStateChanged i="+i);
            if(i == 0){
                pbapState = BtData.PBAP_STATE_SYNC_CONTACTS_PROGRESS;
            }else if(i == Constants.CONTACTS_SYNC_STARTED){
                pbapState = BtData.PBAP_STATE_SYNC_CONTACTS_START;
                notifyContactsSyncStart();
            }else if(i == Constants.CONTACTS_SYNC_FINISHED){
                pbapState = BtData.PBAP_STATE_SYNC_CONTACTS_END;
            }
        }

        @Override
        public void onSyncCalllogStateChanged(int state) {
            Log.d(ContactsHandler.class, "-------onSyncCalllogStateChanged----- state = "+state);
            if(state == com.pateo.bluetooth.logic.util.Constants.CALLLOG_SYNC_FINISHED){
                pbapState = BtData.PBAP_STATE_SYNC_CALLLOG_END;
            }else if(state == com.pateo.bluetooth.logic.util.Constants.CALLLOG_SYNC_ABORTED){
                pbapState = BtData.PBAP_STATE_SYNC_FAILED;
            }else if(state == com.pateo.bluetooth.logic.util.Constants.CALLLOG_SYNC_STARTED){
                pbapState = BtData.PBAP_STATE_SYNC_CALLLOG_START;
                notifyCallLogSyncStart();
            }
        }

        @Override
        public void onContactsListFetched(List<ContactData> list) {
            Log.i(ContactsHandler.class,"onContactsListFetched");
            contacts = list;
            notifyContactsSyncEnd(list);
        }

        @Override
        public void onContactsForDialListFetched(List<ContactMatchInfo> list) {
            Log.i(ContactsHandler.class,"onContactsForDialListFetched");

        }

        @Override
        public void onAllCalllogFetched(List<ContactLog> list) {
            Log.i(ContactsHandler.class,"onAllCalllogFetched ");
            contactLogs = list;
            notifyCallLogSyncEnd(list);
        }

        @Override
        public void refreshContactUI(List<ContactData> list) {
            Log.i(ContactsHandler.class,"refreshContactUI");
            contacts = list;
            notifyContactsChanged(list);
        }

        @Override
        public void refreshCalllogUI(List<ContactLog> list) {
            Log.i(ContactsHandler.class,"refreshCalllogUI");
            contactLogs = list;
            notifyCallLogChanged(list);
        }
    };
}
